package com.emergency.evaluate.service.impl;

import com.emergency.base.domain.Plan;
import com.emergency.base.domain.Scenar;

import com.emergency.common.util.CommonUtils;
import com.emergency.common.util.IdWorker;

import com.emergency.common.util.R;
import com.emergency.evaluate.dao.*;
import com.emergency.evaluate.domain.*;


import com.emergency.evaluate.service.ReportService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;

import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2020/4/9.
 */
@Service
@Transactional
public class ReportServiceImpl implements ReportService{

    //输出日志
    private final static Logger logger = LoggerFactory.getLogger(ManualServiceImpl.class);

    @Autowired
    private ReportDao reportDao;
    @Autowired
    private ManualDao manualDao;
    @Autowired
    private ScoreDao scoreDao;
    @Autowired
    private  AutoscoreDao autoscoreDao;
    @Autowired
    private AutoDao autoDao;
    @Autowired
    private  ScenarDao scenarDao;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private ReportNumDao reportNumDao;


    //通过报告ID查询指标
    @Override
  public   List<Report> findbyID(Long Id ){
        return reportDao.findAllByReportId ( Id );
    }

    //通过报告 id 删除指标
    @Override
   public void deleteById(Long id){
      reportDao.deleteById (id);
    }

    // 保存报告
    @Override
    public  List<Report> save(Long id) {
        //删除report 的相关manual配置
        Manual manual = manualDao.findAllById ( id );
        reportDao.deleteByManual (manual.getId ());
        Report report = new Report ();
        report.setManual ( manualDao.findAllById ( id ) );
        logger.info ( "评估报告生成的时间和编号" );
        if (CommonUtils.isNullOrEmpty ( report.getId () )) {  //评估报告自动赋值ID和创建时间
            report.setId ( idWorker.nextId () );
            report.setCreateTime ( new Date () );
        }

        //演练目的、时间、人员、地点、总时长
        logger.info ( "演练目的" + report.getAim () );

        // 演练时间
        List <Date> startTime = new ArrayList <> ();
        List <Date> endTime = new ArrayList <> ();

        //遍历想定，评估报告显示所有的想定信息，后对选定的想定信息进行评价，例如：此想定环节设计是否合理，考察救援人员哪些救援能力，有哪些硬件条件（装备）

            Scenar scenar = scenarDao.findAllById (manual.getScenar ().getId ());//找到想定
            report.setScenar ( scenar );  //想定来源

            //演练时间
            Date startDate = scenar.getStartTime (); //获取每个想定开始时间
            //计算结束时间
            long end = startDate.getTime () + scenar.getDuration ();
            Date endDate = new Date ();
            endDate.setTime ( end );
            //存入时间数组中
            startTime.add ( startDate );
            endTime.add ( endDate );

        //  报告中可获得的所有数据来源
        Plan plan=manual.getPlan ();
        report.setPlan (plan);//方案来源
        //将方案的起始时间也存入时间数组中
        startTime.add ( plan.getStartTime () );
        endTime.add ( plan.getEndTime () );
        //演练起始时间、结束时间、持续时间
        countTime ( startTime, endTime,report );
        report.setManual ( manual ); //评分总表分数来源
        reportDao.save ( report );
        //删除绑定评估报告ID的统计数据表，创建对应的统计数据类
        reportNumDao.deleteByReportId ( report.getId () );

        //遍历所有分数,分类计算各等级指标
        count ( report,1 );
         logger.info ( "对方案的总结评价" + report.getPlantext () ); //对方案的总结评价
        count ( report,2 );
         logger.info ( "对指挥人员的总结评价" + report.getCommandtext ()); //对指挥人员的总结评价
        count ( report,3 );
         logger.info ( "对救援人员的总结评价" + report.getRescuetext ()); //对救援人员的总结评价
        count ( report,4 );
         logger.info ( "对效果的总结评价" + report.getEffecttext ()); //对总体效果的总结评价
        count ( report,5 );
        logger.info ( "最终评价" + report.getTotaltext ()); //总结评价
        List <ReportNum> reportNumList = reportNumDao.findAllByReport ( report.getId () );
        logger.info ( "数据列表但" + reportNumList); //对总体效果的总结评价

        report.setReportNums (reportNumList);
        reportDao.save ( report );
        logger.info ( "数据列表但" + report.getReportNums ()); //对总体效果的总结评价
        return reportDao.findAllByReportId ( report.getId () );
        }



    private void countTime(List<Date> startTime, List<Date> endTime,Report report) {
        Date minStartTime=startTime.get (0);
        Date maxEndTime=endTime.get(0);

        for(int i=0;i<startTime.size ();i++) {
            if (startTime.get ( i ).before (minStartTime)) {
                minStartTime = startTime.get ( i );  //得到最初开始时间
            }
            logger.info ( "演练开始："+minStartTime );
            report.setStartTime ( minStartTime );
        }

        for(int i=0;i<endTime.size ();i++)
        {  if (endTime.get (i).after (maxEndTime)){
            maxEndTime=endTime.get ( i ) ;  //得到最后的结束时间
        }
            System.out.print ( "演练结束："+maxEndTime );
            report.setEndTime ( maxEndTime );
        }

        //计算演练持续的时间，时间是ms
        //1天=24小时，1小时=60分，1分=60秒，所以两个时间的差再除以60 * 60 * 24换算成天的形式
        int days= (int) ((maxEndTime.getTime ()-minStartTime.getTime ())/1000/(60*60*24));
        int hours= (int)((maxEndTime.getTime ()-minStartTime.getTime ()-24*60*60*1000*days)/1000/(60*60));
        int minutes=(int) ((maxEndTime.getTime ()-minStartTime.getTime ()-24*60*60*1000*days-60*60*1000*hours)/1000/60);
        int seconds=(int) ((maxEndTime.getTime ()-minStartTime.getTime ()-24*60*60*1000*days-60*60*1000*hours-60*1000*minutes)/1000);
        logger.info ("演练持续时间："+days+"天"+hours+"时"+minutes+"分"+seconds+"秒");
        report.setDays ( days );
        report.setHours ( hours );
        report.setMinutes ( minutes );
        report.setSeconds ( seconds );
    }

    private void count(Report report,int kind){
        //计数标志
        int aNum=0;
        int bNum=0;
        int cNum=0;
        int dNum=0;
        int eNum=0;
        //根据类型生成abcde等级(对应12345)的数量
        for(int i=1;i<=5;i++){
            ReportNum reportNum = new ReportNum ();
            if (CommonUtils.isNullOrEmpty ( reportNum.getId ())){
                reportNum.setId ( idWorker.nextId () );
                reportNum.setCreateTime ( new Date (  ) );
            }
            reportNum.setReport ( report );
            reportNum.setType ( kind );
            reportNum.setLevel (i);
            reportNumDao.save ( reportNum );
        }
       //获取分数表
        if(!CommonUtils.isNullOrEmpty ( report.getManual ())) {
            List <Score> scores = scoreDao.findAllByManual ( report.getManual ().getId () );
            for (Score score : scores) {
                //对选定类型指标的统计
                if (score.getExtract ().getIndicator ().getKind () == kind || kind == 5) {
                    switch (score.getLevel ())   //  计算等级数量

                    {
                        case "A":
                            aNum = aNum + 1;
                            break; //A等级指标,
                        case "B":
                            bNum = bNum + 1;
                            break;//B等级指标
                        case "C":
                            cNum = cNum + 1;
                            break;//C等级指标
                        case "D":
                            dNum = dNum + 1;
                            break;//D等级指标
                        case "E":
                            eNum = eNum + 1;
                            break;//E等级指标
                    }
                }
            }
        }
        if(!CommonUtils.isNullOrEmpty ( report.getAuto ())) {
            List <Autoscore> autoscoreList = autoscoreDao.findAllByAuto ( report.getAuto ().getId () );
            for (Autoscore autoscore:autoscoreList) {
                //对选定类型指标的统计
                if (autoscore.getExtract ().getIndicator ().getKind () == kind || kind == 5) {
                    switch (autoscore.getLevel ())   //  计算等级数量

                    {
                        case "A":
                            aNum = aNum + 1;
                            break; //A等级指标,
                        case "B":
                            bNum = bNum + 1;
                            break;//B等级指标
                        case "C":
                            cNum = cNum + 1;
                            break;//C等级指标
                        case "D":
                            dNum = dNum + 1;
                            break;//D等级指标
                        case "E":
                            eNum = eNum + 1;
                            break;//E等级指标
                    }
                }
            }
        }
        //开始绑定等级统计数据
        List <ReportNum> reportNums = reportNumDao.findAllByType ( kind );
        for(ReportNum reportNum:reportNums){
            switch(reportNum.getLevel ()) {
                case 1: reportNum.setNum ( aNum );break;
                case 2: reportNum.setNum ( bNum );break;
                case 3: reportNum.setNum ( cNum );break;
                case 4: reportNum.setNum ( dNum );break;
                case 5: reportNum.setNum ( eNum );break;
            }
            //保存统计数据
            reportNumDao.save ( reportNum );
        }
    }
    @Override
   public List<Report> saveauto(Long autoID){
        //删除report 的相关auto配置
       Auto auto = autoDao.findAllById ( autoID );
       reportDao.deleteByAuto (auto.getId ());
        Report report = new Report ();
        report.setAuto ( autoDao.findAllById ( autoID) );
        logger.info ( "评估报告生成的时间和编号" );

            report.setId ( idWorker.nextId () );
            report.setCreateTime ( new Date () );


        //演练目的、时间、人员、地点、总时长
        logger.info ( "演练目的" + report.getAim () );

        // 演练时间
        List <Date> startTime = new ArrayList <> ();
        List <Date> endTime = new ArrayList <> ();

        //遍历想定，评估报告显示所有的想定信息，后对选定的想定信息进行评价，例如：此想定环节设计是否合理，考察救援人员哪些救援能力，有哪些硬件条件（装备）

        Scenar scenar = scenarDao.findAllById (auto.getScenar ().getId ());//找到想定
        report.setScenar ( scenar );  //想定来源

        //演练时间
        Date startDate = scenar.getStartTime (); //获取每个想定开始时间
        //计算结束时间
        long end = startDate.getTime () + scenar.getDuration ();
        Date endDate = new Date ();
        endDate.setTime ( end );
        //存入时间数组中
        startTime.add ( startDate );
        endTime.add ( endDate );

        //  报告中可获得的所有数据来源
        Plan plan=auto.getPlan ();
        report.setPlan (plan);//方案来源
        //将方案的起始时间也存入时间数组中
        startTime.add ( plan.getStartTime () );
        endTime.add ( plan.getEndTime () );
        //演练起始时间、结束时间、持续时间
        countTime ( startTime, endTime,report );
        report.setAuto (auto); //评分总表分数来源
        reportDao.save ( report );
        //删除绑定评估报告ID的统计数据表，创建对应的统计数据类


        //遍历所有分数,分类计算各等级指标
        count ( report,1 );
        logger.info ( "对方案的总结评价" + report.getPlantext () ); //对方案的总结评价
        count ( report,2 );
        logger.info ( "对指挥人员的总结评价" + report.getCommandtext ()); //对指挥人员的总结评价
        count ( report,3 );
        logger.info ( "对救援人员的总结评价" + report.getRescuetext ()); //对救援人员的总结评价
        count ( report,4 );
        logger.info ( "对效果的总结评价" + report.getEffecttext ()); //对总体效果的总结评价
        count ( report,5 );
        logger.info ( "最终评价" + report.getTotaltext ()); //总结评价
        List <ReportNum> reportNumList = reportNumDao.findAllByReport ( report.getId () );
        logger.info ( "数据列表但" + reportNumList); //对总体效果的总结评价

        report.setReportNums (reportNumList);
        reportDao.save ( report );
        logger.info ( "数据列表但" + report.getReportNums ()); //对总体效果的总结评价
        return reportDao.findAllByReportId ( report.getId () );

    }





@Override
    public  Report get(Long reportId){
    Report report = reportDao.findAllByReport ( reportId );
    report.setReportNums ( reportNumDao.findAllByReport ( reportId ) );
        return report;
    }
}
